use std::error::Error;
use std::path::Path;
use std::fs;
use async_std::task;
use async_recursion::async_recursion;

pub mod analysis;

/// 执行文件读取并解析写入
pub fn exec(path: &str) -> Result<(), Box<dyn Error>> {
    task::block_on(recursion(path.to_string()))?;
    Ok(())
}

/// 使用async递归宏 否则要重写返回为 Future
#[async_recursion]
/// 递归判断文件/文件夹 然后开启线程执行方法
async fn recursion(path_str: String) -> Result<(), Box<dyn Error>> {
    let path = Path::new(path_str.as_str());
    if path.is_file() {
        match path.extension() {
            Some(s) => {
                if s.eq("pr") {
                    println!(" << reading {}", &path_str);
                    task::spawn(thread_exec(path_str)).await;
                } else { println!(" -- continue path cause not .pr : {}", &path_str); }
            }
            _ => { println!(" -- continue path cause nil extension : {}", &path_str); }
        }
    } else if path.is_dir() {
        let dirs = fs::read_dir(path)?;
        for de in dirs {
            if let Some(s) = de?.path().to_str() {
                recursion(s.to_string()).await?;
            };
        }
    } else {
        println!(" -- continue path cause unknown : {}", &path_str);
    }
    Ok(())
}

/// 线程单文件执行方法
async fn thread_exec(path_str: String) {
    //读取
    let s = fs::read_to_string(Path::new(path_str.as_str())).unwrap();
    //解析生成
    let r = analysis::domain(&s);
    //写入
    let rs = path_str.replace(".pr", ".rs");
    fs::write(Path::new(rs.as_str()), r).unwrap();
    println!(" >> created {}", rs);
}
